//+------------------------------------------------------------------+
//|                                      PerformanceAnalysis.mqh |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property link      ""
#property version   "1.00"
#property strict

// 性能指标结构
struct PerformanceMetrics {
    // 收益指标
    double totalReturn;         // 总收益率
    double annualReturn;        // 年化收益率
    double monthlyReturn;       // 月化收益率
    double dailyReturn;         // 日化收益率
    
    // 风险指标
    double maxDrawdown;         // 最大回撤
    double drawdownDuration;    // 回撤持续时间
    double volatility;          // 波动率
    double sharpeRatio;         // 夏普比率
    double sortinoRatio;        // 索提诺比率
    
    // 交易指标
    int totalTrades;            // 总交易次数
    int winningTrades;          // 盈利交易次数
    int losingTrades;           // 亏损交易次数
    double winRate;             // 胜率
    double profitFactor;        // 盈亏比
    double averageWin;          // 平均盈利
    double averageLoss;         // 平均亏损
    double largestWin;          // 最大盈利
    double largestLoss;         // 最大亏损
    
    // 时间指标
    double averageHoldingTime;  // 平均持仓时间
    double maxHoldingTime;      // 最大持仓时间
    double minHoldingTime;      // 最小持仓时间
};

// 性能分析类
class CPerformanceAnalysis {
private:
    // 历史数据
    double m_equityCurve[];     // 权益曲线
    double m_drawdownCurve[];   // 回撤曲线
    datetime m_timeCurve[];     // 时间曲线
    
    // 交易记录
    struct Trade {
        datetime openTime;      // 开仓时间
        datetime closeTime;     // 平仓时间
        double openPrice;       // 开仓价格
        double closePrice;      // 平仓价格
        double profit;          // 盈亏
        double volume;          // 交易量
    };
    Trade m_trades[];           // 交易记录数组
    
    // 性能指标
    PerformanceMetrics m_metrics;  // 性能指标
    
    // 分析参数
    int m_lookbackPeriod;       // 回看周期
    double m_riskFreeRate;      // 无风险利率
    
public:
    // 构造函数
    CPerformanceAnalysis() {
        m_lookbackPeriod = 252;  // 默认一年交易日
        m_riskFreeRate = 0.02;   // 默认2%无风险利率
    }
    
    // 初始化
    bool Initialize(int lookbackPeriod = 252, double riskFreeRate = 0.02) {
        m_lookbackPeriod = lookbackPeriod;
        m_riskFreeRate = riskFreeRate;
        
        return true;
    }
    
    // 更新权益曲线
    void UpdateEquityCurve() {
        int count = ArraySize(m_equityCurve);
        ArrayResize(m_equityCurve, count + 1);
        ArrayResize(m_timeCurve, count + 1);
        
        m_equityCurve[count] = AccountInfoDouble(ACCOUNT_EQUITY);
        m_timeCurve[count] = TimeCurrent();
    }
    
    // 添加交易记录
    void AddTrade(datetime openTime, datetime closeTime, double openPrice,
                 double closePrice, double profit, double volume) {
        int count = ArraySize(m_trades);
        ArrayResize(m_trades, count + 1);
        
        m_trades[count].openTime = openTime;
        m_trades[count].closeTime = closeTime;
        m_trades[count].openPrice = openPrice;
        m_trades[count].closePrice = closePrice;
        m_trades[count].profit = profit;
        m_trades[count].volume = volume;
    }
    
    // 计算性能指标
    void CalculateMetrics() {
        // 计算收益指标
        CalculateReturnMetrics();
        
        // 计算风险指标
        CalculateRiskMetrics();
        
        // 计算交易指标
        CalculateTradeMetrics();
        
        // 计算时间指标
        CalculateTimeMetrics();
    }
    
    // 获取性能指标
    void GetMetrics(PerformanceMetrics &metrics) {
        metrics = m_metrics;
    }
    
    // 生成性能报告
    string GenerateReport() {
        string report = "Performance Analysis Report\n";
        report += "===========================\n\n";
        
        // 收益指标
        report += "Return Metrics:\n";
        report += "Total Return: " + DoubleToString(m_metrics.totalReturn * 100, 2) + "%\n";
        report += "Annual Return: " + DoubleToString(m_metrics.annualReturn * 100, 2) + "%\n";
        report += "Monthly Return: " + DoubleToString(m_metrics.monthlyReturn * 100, 2) + "%\n";
        report += "Daily Return: " + DoubleToString(m_metrics.dailyReturn * 100, 2) + "%\n\n";
        
        // 风险指标
        report += "Risk Metrics:\n";
        report += "Max Drawdown: " + DoubleToString(m_metrics.maxDrawdown * 100, 2) + "%\n";
        report += "Drawdown Duration: " + DoubleToString(m_metrics.drawdownDuration, 0) + " days\n";
        report += "Volatility: " + DoubleToString(m_metrics.volatility * 100, 2) + "%\n";
        report += "Sharpe Ratio: " + DoubleToString(m_metrics.sharpeRatio, 2) + "\n";
        report += "Sortino Ratio: " + DoubleToString(m_metrics.sortinoRatio, 2) + "\n\n";
        
        // 交易指标
        report += "Trade Metrics:\n";
        report += "Total Trades: " + IntegerToString(m_metrics.totalTrades) + "\n";
        report += "Winning Trades: " + IntegerToString(m_metrics.winningTrades) + "\n";
        report += "Losing Trades: " + IntegerToString(m_metrics.losingTrades) + "\n";
        report += "Win Rate: " + DoubleToString(m_metrics.winRate * 100, 2) + "%\n";
        report += "Profit Factor: " + DoubleToString(m_metrics.profitFactor, 2) + "\n";
        report += "Average Win: " + DoubleToString(m_metrics.averageWin, 2) + "\n";
        report += "Average Loss: " + DoubleToString(m_metrics.averageLoss, 2) + "\n";
        report += "Largest Win: " + DoubleToString(m_metrics.largestWin, 2) + "\n";
        report += "Largest Loss: " + DoubleToString(m_metrics.largestLoss, 2) + "\n\n";
        
        // 时间指标
        report += "Time Metrics:\n";
        report += "Average Holding Time: " + DoubleToString(m_metrics.averageHoldingTime, 0) + " minutes\n";
        report += "Max Holding Time: " + DoubleToString(m_metrics.maxHoldingTime, 0) + " minutes\n";
        report += "Min Holding Time: " + DoubleToString(m_metrics.minHoldingTime, 0) + " minutes\n";
        
        return report;
    }
    
private:
    // 计算收益指标
    void CalculateReturnMetrics() {
        int count = ArraySize(m_equityCurve);
        if(count < 2) return;
        
        // 计算总收益率
        m_metrics.totalReturn = (m_equityCurve[count-1] - m_equityCurve[0]) / m_equityCurve[0];
        
        // 计算年化收益率
        double years = (m_timeCurve[count-1] - m_timeCurve[0]) / (365.0 * 24.0 * 60.0 * 60.0);
        m_metrics.annualReturn = MathPow(1.0 + m_metrics.totalReturn, 1.0 / years) - 1.0;
        
        // 计算月化收益率
        m_metrics.monthlyReturn = MathPow(1.0 + m_metrics.annualReturn, 1.0 / 12.0) - 1.0;
        
        // 计算日化收益率
        m_metrics.dailyReturn = MathPow(1.0 + m_metrics.annualReturn, 1.0 / 252.0) - 1.0;
    }
    
    // 计算风险指标
    void CalculateRiskMetrics() {
        int count = ArraySize(m_equityCurve);
        if(count < 2) return;
        
        // 计算回撤曲线
        ArrayResize(m_drawdownCurve, count);
        double peak = m_equityCurve[0];
        m_drawdownCurve[0] = 0.0;
        
        for(int i = 1; i < count; i++) {
            if(m_equityCurve[i] > peak) {
                peak = m_equityCurve[i];
            }
            m_drawdownCurve[i] = (peak - m_equityCurve[i]) / peak;
        }
        
        // 计算最大回撤
        m_metrics.maxDrawdown = 0.0;
        for(int i = 0; i < count; i++) {
            m_metrics.maxDrawdown = MathMax(m_metrics.maxDrawdown, m_drawdownCurve[i]);
        }
        
        // 计算回撤持续时间
        int maxDrawdownStart = 0;
        int maxDrawdownEnd = 0;
        bool inDrawdown = false;
        
        for(int i = 0; i < count; i++) {
            if(m_drawdownCurve[i] > 0.0 && !inDrawdown) {
                inDrawdown = true;
                maxDrawdownStart = i;
            }
            else if(m_drawdownCurve[i] == 0.0 && inDrawdown) {
                inDrawdown = false;
                maxDrawdownEnd = i;
            }
        }
        
        m_metrics.drawdownDuration = (m_timeCurve[maxDrawdownEnd] - m_timeCurve[maxDrawdownStart]) / (24.0 * 60.0 * 60.0);
        
        // 计算波动率
        double sum = 0.0;
        double sumSquared = 0.0;
        
        for(int i = 1; i < count; i++) {
            double return_i = (m_equityCurve[i] - m_equityCurve[i-1]) / m_equityCurve[i-1];
            sum += return_i;
            sumSquared += return_i * return_i;
        }
        
        double mean = sum / (count - 1);
        m_metrics.volatility = MathSqrt((sumSquared / (count - 1)) - (mean * mean));
        
        // 计算夏普比率
        m_metrics.sharpeRatio = (m_metrics.annualReturn - m_riskFreeRate) / (m_metrics.volatility * MathSqrt(252));
        
        // 计算索提诺比率
        double sumDownside = 0.0;
        int downsideCount = 0;
        
        for(int i = 1; i < count; i++) {
            double return_i = (m_equityCurve[i] - m_equityCurve[i-1]) / m_equityCurve[i-1];
            if(return_i < 0) {
                sumDownside += return_i * return_i;
                downsideCount++;
            }
        }
        
        double downsideDeviation = MathSqrt(sumDownside / downsideCount);
        m_metrics.sortinoRatio = (m_metrics.annualReturn - m_riskFreeRate) / (downsideDeviation * MathSqrt(252));
    }
    
    // 计算交易指标
    void CalculateTradeMetrics() {
        int count = ArraySize(m_trades);
        if(count == 0) return;
        
        m_metrics.totalTrades = count;
        m_metrics.winningTrades = 0;
        m_metrics.losingTrades = 0;
        double totalProfit = 0.0;
        double totalLoss = 0.0;
        m_metrics.largestWin = 0.0;
        m_metrics.largestLoss = 0.0;
        
        for(int i = 0; i < count; i++) {
            if(m_trades[i].profit > 0) {
                m_metrics.winningTrades++;
                totalProfit += m_trades[i].profit;
                m_metrics.largestWin = MathMax(m_metrics.largestWin, m_trades[i].profit);
            }
            else {
                m_metrics.losingTrades++;
                totalLoss += MathAbs(m_trades[i].profit);
                m_metrics.largestLoss = MathMin(m_metrics.largestLoss, m_trades[i].profit);
            }
        }
        
        m_metrics.winRate = (double)m_metrics.winningTrades / count;
        m_metrics.profitFactor = totalProfit / totalLoss;
        m_metrics.averageWin = totalProfit / m_metrics.winningTrades;
        m_metrics.averageLoss = totalLoss / m_metrics.losingTrades;
    }
    
    // 计算时间指标
    void CalculateTimeMetrics() {
        int count = ArraySize(m_trades);
        if(count == 0) return;
        
        double totalHoldingTime = 0.0;
        m_metrics.maxHoldingTime = 0.0;
        m_metrics.minHoldingTime = DBL_MAX;
        
        for(int i = 0; i < count; i++) {
            double holdingTime = (m_trades[i].closeTime - m_trades[i].openTime) / 60.0;  // 转换为分钟
            totalHoldingTime += holdingTime;
            m_metrics.maxHoldingTime = MathMax(m_metrics.maxHoldingTime, holdingTime);
            m_metrics.minHoldingTime = MathMin(m_metrics.minHoldingTime, holdingTime);
        }
        
        m_metrics.averageHoldingTime = totalHoldingTime / count;
    }
}; 